Bu yazımızda sizinle React uygulamasında basit ama kullanışlı bir sayfalandırma uygulamasını anlatacağız. Sayfalandırma, web site uygulamanızda çok fazla veri bulunduğunda bu verilerin sayfalar halinde kullanıcıya gösterilmesi, kullanıcının ilerletmesi ile diğer sayfaya geçilip verilerin gösterilmesine yarar. Sayfalandırma uygulamalarının bir çok çeşidi olmak la beraber bu yazıda Önceki - Sonraki sayfa şeklinde olanı göstereceğiz. Uygulamanızda sayfanın sonunda aşağıdaki şekillerde gözükecek. Ortada toplam sayfa sayısı yazacak. İleride veya geride başka sayfa yok ise buton disable olacak. Ayrıca sayfa değiştirince, sayfa başına geri dönecek.



Şimdi adım adım yapmaya başlayalım.
1. Adım - Sayfalandırma Komponentini oluşturalım
Bu komponentte stil özelliklerini tanımlıyoruz. İşlevselliği buradan yapmayacağız. Css olarak tailwind kullanıyoruz, siz farklı şekilde yapabilirsiniz. Mantık olarak böyle bir sayfanızın olması gerekiyor. Komponentte aktif ve pasif buton stillerini tanımladık. Toplam sayfa sayısı, mevcuttaki sayfa ve sayfa değiştirme fonksiyonunu üst komponentten alıyoruz.
import { FaAngleLeft, FaAngleRight } from"react-icons/fa";
const disableButtonClassName =
"cursor-auto flex gap-1 justify-center items-center disabled:opacity-50 text-color1 hover:text-color2 border rounded-2xl py-3 px-4";
const activeButtonClassName =
"flex gap-1 justify-center items-center text-color1";
interface PaginationProps {
totalPages: number;
currentPage: number;
onPageChange: (page: number) =>void;
}
export default function Pagination({
totalPages,
currentPage,
onPageChange,
}: PaginationProps) {
const prevPage = currentPage > 1;
const nextPage = currentPage < totalPages;
const handlePrevPage = () => {
if (prevPage) {
onPageChange(currentPage - 1);
}
};
const handleNextPage = () => {
if (nextPage) {
onPageChange(currentPage + 1);
}
};
return (
<divclassName="space-y-2 pb-3 pt-6 md:space-y-5">
<navclassName="flex justify-between items-center">
<divclassName="flex items-center">
<button
className={
prevPage ? activeButtonClassName : disableButtonClassName
}
onClick={handlePrevPage}
disabled={!prevPage}
>
<FaAngleLeft/>
Önceki
</button>
</div>
<spanclassName="text-color1">
{currentPage} of {totalPages}
</span>
<divclassName="flex items-center">
<button
className={
nextPage ? activeButtonClassName : disableButtonClassName
}
onClick={handleNextPage}
disabled={!nextPage}
>
Sonraki
<FaAngleRight/> </button>
</div>
</nav>
</div>
);}
2. Adım - Sayfalandırma için Custom Hook hazırlayalım.
Sayfalandırma componentini bir kez oluşturduktan sonra uygulamamızın bir çok yerinde hazır olarak kullanabilmek için bir custom hook hazırlayalım. Bu sayede bu custom hook'u uygulamamzın her yerinde kullanabiliriz. Sayfalandırma işleminin işlevselliğini bu custom hook ile kazandıracağız. Bunun için uygulamanızın içinde usePagination.ts (veya js) isimli bir dosya açın.
import { useState, Dispatch, SetStateAction } from"react";
interface UsePaginationResult <T> {
totalPages: number;
displayPosts: T[];
setCurrentPage: Dispatch <SetStateAction <number> >;
onPageChange: (page:number) => void;
currentPage: number;
}
export const usePagination = <T> (
data : T[],
postsPerPage : number = 3
) : UsePaginationResult<T> => {
const [currentPage, setCurrentPage] = useState <number> (1);
const totalPages = Math.ceil(data?.length / postsPerPage);
const startIndex = (currentPage - 1) * postsPerPage;
const endIndex = startIndex + postsPerPage;
const displayPosts = data ? data.slice (startIndex, endIndex) : [];
const onPageChange = (page:number) => {
if (page >= 1 && page <= totalPages) {
setCurrentPage(page);
}
};
return {
totalPages,
displayPosts,
setCurrentPage,
onPageChange,
currentPage,
};
};
Bu dosyada typescript tanımlarının yapıyoruz. Bu hook'u kullanırken, kullandığımız componentten, sayfada kaç post veya kaç data gözükeceği bilgisi ile tüm datayı gönderiyoruz. Hook ise biza toplam sayfa sayısı, gösterilecek öğeler, şu anki sayfa, sayfa değiştirme fonksiyonu ve mevcut sayfayı ayarlama fonksiyonunu veriyor.
3. Adım - Kullanıcı Sayfasında Sayfalandırmayı Kullanma
Sayfalandırma için stil komponentini ve işlevselliği için usePagination hook'unu oluşturduk. Şimdi bunu uygulama sayfamızda nasıl kullanacağımıza bakalım. Bunun için örnek bir senaryo yapalım. Veritabanından aldığımız kategri datasını listelediğimiz bir tablomuz var. Bu tabloyu her 15 data'dan sonra değişecek şekilde sayfalandıralım.
import CategoryTableItem from "./CategoryTableItem";
import Pagination from "@/Components/Layouts/Pagination";
import { usePagination } from "@/lib/hooks/usePagination";
import { CategoryType } from "@/lib/types/types";
interface CategoryTableProps {
allCategories: CategoryType[];
}
const CategoryTable = ({ allCategories }:CategoryTableProps) => {
const { totalPages, displayPosts, onPageChange, currentPage } = usePagination(
allCategories,
15
);
return (
<>
<divclassName="relative rounded-lg overflow-x-auto mt-4 border border-gray-400 scrollbar-hide">
<tableclassName="w-full text-sm text-gray-500">
<theadclassName="text-gray-700 bg-gray-50 text-base">
<tr>
<thscope="col"className="px-6 py-3 text-left">
İsim
</th>
<thscope="col"className="p-2">
Renk
</th>
<thscope="col"className="px-4 py-1 text-left">
İşlemler
</th>
</tr>
</thead>
<tbody>
{displayPosts?.map((category) => {
return (
<CategoryTableItemkey={category._id}category={category}/>
);
})}
</tbody>
</table>
</div>
{totalPages > 1 && (
<Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={onPageChange}
/>
)}
export default CategoryTable;
Yukarıda verilen örnekte, İlk başta hook'u kullanarak sayfalandırma verilerimizi oluşturduk. Allcategories datasını ve 15 data'da bir sayfa değiştir kuralını önderdik, ordan gösterilecek dataları ve diğer bilgileri aldık. Jsx kodumuzun son satırına da 1. adımda oluşturduğumuz komponenti koyduk, ona vereceğimiz proplar da zaten usePagination hook'undan aldığımız veriler. Bu şekilde bütünleşik olarak sayfalandırma sistemini bu sayfaya kurmuş olduk.
Bu şekilde başka sayfalarda da aynı şekilde önce hook'u çağırıp, Jsx kodunun sonuna komponenti ekleyerek sayfalandırmayı kullanabiliriz. Bu yazımız da burada sona eriyor. Konu ile alakalaı herhangi bir soru, sorun, öneri veya eklemeniz olursa aşağıya yorum kısmına yazabilirsiniz veya iletişim kısmına yazarak sorabilirsiniz. İyi çalışmalar.